package ci.web.util;

import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import javassist.ClassPool;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;
/**
 * 
 * @author zhh
 */
public class JxHelper {
	
	/**
	 * 获取方法的参数名
	 * @param m
	 * @return
	 */
	public static String[] getParamNames(Executable m){
		ClassLoader loader = m.getDeclaringClass().getClassLoader();
		ClassPool pool = null;
		if(loader instanceof CiClassLoader){
			pool = ((CiClassLoader)loader).getClassPool();
		}else{
			pool = ClassPool.getDefault();
		}
		return getParamNames(pool, m);
	}
	/**
	 * 获取方法的参数名
	 * @param pool
	 * @param m
	 * @return
	 */
    public static String[] getParamNames(ClassPool pool, Executable m) {
		try {
			CtClass cc = pool.get(m.getDeclaringClass().getName());
			Class<?>[] pts = m.getParameterTypes();
			String[] ptss = new String[pts.length];
			for (int i = 0; i < pts.length; i++) {
				ptss[i] = pts[i].getName();
			}
			if (m instanceof Method) {
				return getParamNames(cc.getDeclaredMethod(m.getName(), pool.get(ptss)));
			}
			return getParamNames(cc.getDeclaredConstructor(pool.get(ptss)));
		} catch (NotFoundException e) {
			throw new RuntimeException(e.getMessage() + " Fail-paramNames");
		}
    }
    protected static String[] getParamNames(CtBehavior cm) throws NotFoundException {
        MethodInfo methodInfo = cm.getMethodInfo();
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute
                .getAttribute(LocalVariableAttribute.tag);
        String[] names = new String[cm.getParameterTypes().length];
        int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
        for (int i = 0; i < names.length; i++) {
        	names[i] = attr.variableName(i + pos);
        }
        return names;
    }
}
